/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ProcessSelectionDialog.java
 *
 * Created on Dec 28, 2009, 12:02:43 PM
 */

package dnl.jexem.prcs.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.table.AbstractTableModel;

import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.HighlighterFactory;

import dnl.jexem.prcs.JavaProcessInfo;
import dnl.jexem.prcs.ProcessInfo;
import dnl.jexem.prcs.ProcessUtils;

/**
 * 
 * @author daniel
 */
public class ProcessSelectionDialog extends javax.swing.JDialog {

	private static final long serialVersionUID = 1L;

	private Map<Integer, ProcessInfo> processInfos;
	private ProcessInfo selectedProcess;
	
	/** Creates new form ProcessSelectionDialog */
	public ProcessSelectionDialog(java.awt.Frame parent, boolean modal) {
		super(parent, modal);
		initComponents();
	}

	public ProcessInfo getSelectedProcess() {
		return selectedProcess;
	}
	
	public void resolveSelectedProcess() {
		int selectedRow = piTable.getSelectedRow();
		JXTable jxTable = (JXTable) piTable;
		Integer pid = (Integer) jxTable.getModel().getValueAt(
				jxTable.convertRowIndexToModel(selectedRow), 0);
		selectedProcess = processInfos.get(pid);
	}

	public void showJavaProcesses() {
		List<JavaProcessInfo> javaProcesses = ProcessUtils.getJavaProcesses();
		setJavaProcessInfos(javaProcesses);
	}

	public void showProcesses() {
		setProcessInfos(ProcessUtils.getProcesses());
	}

	private void setJavaProcessInfos(List<JavaProcessInfo> infos) {
		populateInfos(infos);
		JpiTableModel tm = new JpiTableModel(infos);
		piTable.setModel(tm);
		initTable();
	}

	private void populateInfos(List<? extends ProcessInfo> infos) {
		processInfos = new HashMap<Integer, ProcessInfo>();
		for (ProcessInfo pi : infos) {
			processInfos.put(pi.getProcessID(), pi);
		}
	}

	public void setProcessInfos(List<ProcessInfo> infos) {
		populateInfos(infos);
		PiTableModel tm = new PiTableModel(infos);
		piTable.setModel(tm);
		initTable();
	}

	private void initTable() {
		JXTable jxTable = (JXTable) piTable;
		jxTable.addHighlighter(HighlighterFactory.createAlternateStriping());
		jxTable.setRolloverEnabled(true);
		jxTable.setColumnControlVisible(true);
		jxTable.setHorizontalScrollEnabled(true);
		jxTable.packAll();
	}

	static class JpiTableModel extends AbstractTableModel {

		private static final long serialVersionUID = 1L;

		List<JavaProcessInfo> infos;

		public JpiTableModel(List<JavaProcessInfo> infos) {
			this.infos = infos;
		}

		@Override
		public int getRowCount() {
			return infos.size();
		}

		@Override
		public int getColumnCount() {
			return 3;
		}

		@Override
		public String getColumnName(int column) {
			switch (column) {
			case 0:
				return "pid";
			case 1:
				return "main/jar";
			case 2:
				return "args";
			}
			return null;
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			JavaProcessInfo pi = infos.get(rowIndex);
			switch (columnIndex) {
			case 0:
				return pi.getProcessID();
			case 1:
				return pi.getMainOrJar();
			case 2:
				return pi.getArguments();
			}
			return null;
		}

	}

	static class PiTableModel extends AbstractTableModel {

		private static final long serialVersionUID = 1L;

		List<ProcessInfo> infos;

		public PiTableModel(List<ProcessInfo> infos) {
			this.infos = infos;
		}

		@Override
		public int getRowCount() {
			return infos.size();
		}

		@Override
		public int getColumnCount() {
			return 3;
		}

		@Override
		public String getColumnName(int column) {
			switch (column) {
			case 0:
				return "pid";
			case 1:
				return "parent pid";
			case 2:
				return "cmd";
			case 3:
				return "args";
			}
			return null;
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			ProcessInfo pi = infos.get(rowIndex);
			switch (columnIndex) {
			case 0:
				return pi.getProcessID();
			case 1:
				return pi.getParentProcessID();
			case 2:
				return pi.getCmd();
			case 3:
				return pi.getArguments();
			}
			return null;
		}

	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// <editor-fold defaultstate="collapsed"
	// <editor-fold defaultstate="collapsed"
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        okJB = new javax.swing.JButton();
        cancelJB = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        piTable = new org.jdesktop.swingx.JXTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Process List");

        jPanel1.setPreferredSize(new java.awt.Dimension(400, 40));

        jLabel1.setFont(new java.awt.Font("DejaVu Sans", 1, 13));
        jLabel1.setText("Select Process From List:");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 219, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(169, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_START);

        jPanel2.setPreferredSize(new java.awt.Dimension(400, 40));

        okJB.setText("OK");
        okJB.setPreferredSize(new java.awt.Dimension(55, 29));
        okJB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okJBActionPerformed(evt);
            }
        });
        jPanel2.add(okJB);

        cancelJB.setText("Cancel");
        cancelJB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelJBActionPerformed(evt);
            }
        });
        jPanel2.add(cancelJB);

        getContentPane().add(jPanel2, java.awt.BorderLayout.PAGE_END);

        jScrollPane1.setPreferredSize(new java.awt.Dimension(375, 500));

        piTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(piTable);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancelJBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelJBActionPerformed
        setVisible(false);
    }//GEN-LAST:event_cancelJBActionPerformed

	private void okJBActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_okJBActionPerformed
        resolveSelectedProcess();
		setVisible(false);
	}// GEN-LAST:event_okJBActionPerformed

	// /**
	// * @param args
	// * the command line arguments
	// */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				ProcessSelectionDialog dialog = new ProcessSelectionDialog(
						new javax.swing.JFrame(), true);
				dialog.showJavaProcesses();
				dialog.addWindowListener(new java.awt.event.WindowAdapter() {
					public void windowClosing(java.awt.event.WindowEvent e) {
						System.exit(0);
					}
				});
				dialog.setVisible(true);
				ProcessInfo selectedProcess = dialog.getSelectedProcess();
				System.out.println(selectedProcess.toStringNixStyle());
			}
		});
	}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelJB;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton okJB;
    private javax.swing.JTable piTable;
    // End of variables declaration//GEN-END:variables

}
